﻿using System;
using CoreTypes;
using System.Data;
using System.Linq;
using System.Text;
using System.Custom;
using System.Drawing;
using System.Windows.Forms;
using System.Custom.Window;
using System.Custom.Drawing;
using System.ComponentModel;
using System.Collections.Generic;
using System.Collections.Specialized;

namespace XmppServiceTransport
{
   internal partial class RegisterWidget : UserControl, IRegisterWidget
   {
      int FCurrentStep;
      StringCollection FSteps;
      RegistrationInfo FRegInfo;
      Point zeroPoint = new Point(0, 0);

      IBaseCommunicator FCommunicator;
      XmppServiceConfig FServiceConfig;
      CommunicationServiceObjectBase FServiceDriver;

      public RegisterWidget(XmppServiceConfig config)
      {
         InitializeComponent();

         FServiceConfig = config;
         FServiceDriver = config.Service.Driver;
         FCommunicator = FServiceDriver.Communicator;

         FCurrentStep = 0;
         comboBoxLanguage.SelectedIndex = 0;

         FSteps = new StringCollection();
         FSteps.AddRange(new string[] { "Intro", "Data", /*"HumanCheck",*/ "Finish" });
         foreach (Panel panel in Controls)
         {
            panel.Visible = false;
            panel.Dock = DockStyle.Fill;
         }

         textBoxServer.Text = config.Host;
      }

      private bool ValidateStep()
      {
         if (FCurrentStep < 0) return true;

         if (FSteps[FCurrentStep] == "Data")
         {
            if (string.IsNullOrEmpty(textBoxJid.Text))
            {
               MessageBox.Show(ResourceWrapper.GetString("S_You_can_not_have_an_empty_nick"), FindForm().Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
               return false;
            }
            if (string.IsNullOrEmpty(textBoxPassword.Text) || textBoxPassword.Text.Length < 4)
            {
               MessageBox.Show(ResourceWrapper.GetString("S_Password_cannot_be_empty"), FindForm().Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
               return false;
            }
            if (textBoxPassword.Text != textBoxConfirmPassword.Text)
            {
               MessageBox.Show(ResourceWrapper.GetString("S_Password_confirmation_is_incorrect"), FindForm().Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
               return false;
            }
         }
         else if (FSteps[FCurrentStep] == "HumanCheck")
         {
            if (string.IsNullOrEmpty(textBoxHumanCheckCode.Text))
            {
               MessageBox.Show(ResourceWrapper.GetString("S_Enter_simbols_on_the_picture"), FindForm().Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
               return false;
            }
         }
         return true;
      }
      private void DoRegistration()
      {
         if (FRegInfo == null) FRegInfo = new RegistrationInfo();

         FRegInfo.Nickname = textBoxJid.Text;
         FRegInfo.ServiceConfig = FServiceConfig;
         FRegInfo.Language = comboBoxLanguage.Text;
         FRegInfo.DesiredLogin = textBoxJid.Text;
         FRegInfo.DesiredPassword = textBoxPassword.Text;
         FRegInfo.HumanCheckCode = textBoxHumanCheckCode.Text;

         ShowProgress("Creating account. Please wait...");

         FCommunicator.CreateAccount(FRegInfo);
      }
      private void ShowPage(string name)
      {
         foreach (Panel panel in Controls)
         {
            if (panel.Name == "panel" + name)
            {
               panel.Visible = true;
               panel.BringToFront();
               if (panel.Tag != null) panel.FindForm().Text = (string)panel.Tag;
            }
            else
            {
               panel.Visible = false;
            }
         }
         if (name == "Intro" && Started != null) Started(this, null);
         else if (name == "Finish" && Finished != null) Finished(this, null);
      }
      private void ShowInfo(string info)
      {
         ShowPage("Progress");
         labelInfoText.Text = info;
         progressBar.Visible = false;
         labelInfoText.Visible = true;
         labelProgress.Visible = false;
         labelInfoText.ForeColor = SystemColors.WindowText;
      }
      private void ShowProgress(string text)
      {
         ShowPage("Progress");
         labelProgress.Text = text;
         progressBar.Visible = true;
         labelProgress.Visible = true;
         labelInfoText.Visible = false;
         if (Progress != null) Progress(this, null);
      }
      private void ShowFinish(string comment)
      {
         FCurrentStep = FSteps.IndexOf("Finish");
         ShowPage(FSteps[FCurrentStep]);

         labelFinish.Text = comment;
      }
      private void ShowError(ServiceOperationException error)
      {
         ShowPage("Progress");
         progressBar.Visible = false;
         labelProgress.Visible = false;
         labelInfoText.Visible = true;
         labelInfoText.Text = error.Message;
         labelInfoText.ForeColor = Color.Red;
         if (Faulted != null) Faulted(this, null);
      }

      public bool IsFinished
      {
         get
         {
            if (FCurrentStep < 0) return false;

            return FSteps[FCurrentStep] == "Finish";
         }
      }

      public event EventHandler Started;
      public event EventHandler Faulted;
      public event EventHandler Finished;
      public event EventHandler Progress;
      public event EventHandler Removing;
      public event EventHandler NextAllowed;
      public event EventHandler NextBlocked;

      public bool Next()
      {
         if (!ValidateStep()) return false;

         if (FSteps[FCurrentStep] == "Data" || FSteps[FCurrentStep] == "HumanCheck")
         {
            DoRegistration();
            return false;
         }
         else
         {
            if (FCurrentStep < FSteps.Count - 1) FCurrentStep++;
            ShowPage(FSteps[FCurrentStep]);
         }
         return true;
      }
      public void Back()
      {
         if (FCurrentStep > 0) FCurrentStep--;
         ShowPage(FSteps[FCurrentStep]);
      }
      public void Start()
      {
         FRegInfo = null;
         FCurrentStep = 0;
         ShowPage(FSteps[FCurrentStep]);
         if (NextAllowed != null) NextAllowed(this, null);
      }

      private void panel_Paint(object sender, PaintEventArgs e)
      {
         // Check for NULL for design mode
         if (FCommunicator != null) FCommunicator.DrawTheme(FCommunicator.ColorTheme, e.Graphics, (sender as Control).ClientRectangle, ColorThemeObject.ToolStrip);
      }
      private void linkSettings_Click(object sender, EventArgs e)
      {
         FServiceDriver.ShowDriverSettings(FServiceConfig.Name);
      }
      private void textBoxIdentifier_Leave(object sender, EventArgs e)
      {
         toolTipInvalidInput.Hide(textBoxJid);
      }
      private void communicator_CreateAccountState(object sender, NetworkOperationEventArgs e)
      {
         if (e.Error != null)
         {
            if (e.Error.ErrorCode == "Id")
            {
               FCurrentStep = FSteps.IndexOf("Data");
               ShowPage(FSteps[FCurrentStep]);

               textBoxJid.Select();
               toolTipInvalidInput.ToolTipTitle = "Invalid ID";
               toolTipInvalidInput.ToolTipIcon = ToolTipIcon.Warning;
               toolTipInvalidInput.Show(textBoxJid.Text + " already registered or incompatible.", textBoxJid, 5, -70, 7000);
               
               if (Faulted != null) Faulted(this, null);
               if (NextAllowed != null) NextAllowed(this, null);
            }
            else
            {
               FCurrentStep = 0;
               ShowError(e.Error);
            }
         }
         else
         {
            if (e.State == OperationState.Completed)
            {
               ShowFinish("You are successfully registered as " + e.Account.ToString() + ".");
            }
            else if (e.State == OperationState.Callback)
            {
               if (FRegInfo.HumanCheckImage != null)
               {
                  pictureBoxHumanCheck.Image = FRegInfo.HumanCheckImage;
                  FCurrentStep = FSteps.IndexOf("HumanCheck");
                  ShowPage(FSteps[FCurrentStep]);
               }
               else
               {
                  DoRegistration();
               }
            }
         }
      }
   }
}
